/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.inspur.edp.jittojava.core.persistence;

import com.inspur.edp.lcm.metadata.api.mvnEntity.MavenPackageRefs;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

public class GenerateRepository {

    public void updateModuleRefs(String pomPath, List<MavenPackageRefs> mavenPackageRefs, boolean appendFlag) {
        if (mavenPackageRefs == null || mavenPackageRefs.size() < 1) {
            return;
        }

        Model model = getModel(pomPath);
        if (model == null) {
            throw new RuntimeException("解析pom失败：" + pomPath);
        }

        if (appendFlag && dependenciesContainsAll(model.getDependencies(), mavenPackageRefs)) {
            return;
        }

        List<Dependency> dependencies = appendFlag ? getDependencies(model.getDependencies(), mavenPackageRefs) : getDependencies(mavenPackageRefs);
        model.setDependencies(dependencies);
        saveModel(pomPath, model);
    }

    private boolean dependenciesContainsAll(List<Dependency> dependencies, List<MavenPackageRefs> mavenPackageRefs) {
        if (mavenPackageRefs == null) {
            return true;
        }
        for (MavenPackageRefs ref : mavenPackageRefs) {
            boolean existFlag = false;
            for (Dependency dependency : dependencies) {
                if (dependency.getGroupId().equals(ref.getGroupId())
                    && dependency.getArtifactId().equals(ref.getArtifactId())
                    && dependency.getVersion().equals(ref.getVersion().substring(1))) {
                    existFlag = true;
                    break;
                }
            }
            if (!existFlag) {
                return false;
            }
        }
        return true;
    }

    private List<Dependency> getDependencies(List<MavenPackageRefs> mavenPackageRefs) {
        ArrayList<Dependency> dependencies = new ArrayList<>();
        mavenPackageRefs.forEach(ref -> {
            Dependency dependency = new Dependency();
            dependency.setGroupId(ref.getGroupId());
            dependency.setArtifactId(ref.getArtifactId());
            dependency.setVersion(ref.getVersion().substring(1));
            dependencies.add(dependency);
        });
        return dependencies;
    }

    private List<Dependency> getDependencies(List<Dependency> dependencies, List<MavenPackageRefs> mavenPackageRefs) {
        if (dependencies == null) {
            dependencies = new ArrayList<>();
        }
        List<Dependency> finalDependencies = dependencies;
        mavenPackageRefs.forEach(ref -> {
            int existInt = -1;
            for (int i = 0; i < finalDependencies.size(); i++) {
                if (ref.getArtifactId().equals(finalDependencies.get(i).getArtifactId())
                    && ref.getGroupId().equals(finalDependencies.get(i).getGroupId())) {
                    existInt = i;
                    break;
                }
            }
            if (existInt != -1) {
                finalDependencies.get(existInt).setVersion(ref.getVersion().substring(1));
            } else {
                Dependency dependency = new Dependency();
                dependency.setGroupId(ref.getGroupId());
                dependency.setArtifactId(ref.getArtifactId());
                dependency.setVersion(ref.getVersion().substring(1));
                finalDependencies.add(dependency);
            }
        });
        return finalDependencies;
    }

    private Model getModel(String pomPath) {
        try {
            FileInputStream fis = new FileInputStream(pomPath);
            MavenXpp3Reader reader = new MavenXpp3Reader();
            Model model = reader.read(fis);
            fis.close();
            return model;
        } catch (XmlPullParserException | IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void saveModel(String pomPath, Model model) {
        MavenXpp3Writer writer = new MavenXpp3Writer();
        try {
            FileOutputStream fos = new FileOutputStream(pomPath);
            writer.write(fos, model);
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
